package com.cf.user.login.service;

import com.cf.constant.EnumReturnCode;
import com.cf.crud.service.AbsBaseService;
import com.cf.exception.BizException;
import com.cf.expire.ExpireService;
import com.cf.id.SnowflakeId;
import com.cf.mapper.BeanMapper;
import com.cf.message.service.PhoneCodeService;
import com.cf.user.core.EnumExpirePrefixKey;
import com.cf.user.core.EnumUserType;
import com.cf.user.core.part.wx.WxUserInfo;
import com.cf.user.login.dao.ThirdPartUserDao;
import com.cf.user.login.dao.UserInfoDao;
import com.cf.user.login.model.ThirdPartUser;
import com.cf.user.login.model.UserInfo;
import com.cf.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * game-server-UserInfoService
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/6/13 上午 09:54
 */
@Slf4j
public class UserInfoServiceImpl extends AbsBaseService<UserInfo, UserInfoDao> implements UserInfoService {

    @Autowired
    private SnowflakeId id;

    @Autowired
    private BeanMapper beanMapper;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private ThirdPartUserDao thirdPartUserDao;

    @Autowired
    private PhoneCodeService phoneCodeService;

    private List<UserInfo> virtualUsers = new ArrayList();

    private Random virtualUserRandom = new Random();


    private AtomicBoolean virtualFlag = new AtomicBoolean(false);

    @Override
    public UserInfo getUserInfo(String userId) {
        if (!NumberUtil.isDigit(userId)) {
            throw new BizException(EnumReturnCode.ERROR.getCode(), "查找的用户Id数据错误！");
        }
        Long lUid = Long.valueOf(userId);
        return userInfoDao.selectByPrimaryKey(lUid);
    }

    @Override
    public UserInfo virtualUserInfo() {
        initVirtualUser();
        if (virtualUsers.size() <= 0)
            return null;
        return virtualUsers.get(virtualUserRandom.nextInt(virtualUsers.size()));
    }

    private void initVirtualUser() {
        if (!virtualFlag.get()) {
            List<UserInfo> us = userInfoDao.selectByType(EnumUserType.VIRTUAL.getCode());
            if (us.size() > 0)
                virtualUsers.addAll(us);
            virtualFlag.set(true);
        }
    }

    @Override
    public UserInfo login(String account, String pwd) {

        if (StringUtils.isEmpty(account) || StringUtils.isEmpty(pwd)) {
            throw new BizException(EnumReturnCode.NEED_LOGIN.getCode(), "account或者pwd不在参数列表中");
        }
        ThirdPartUser thirdPartUser = thirdPartUserDao.selectByAccountAndPwd(account, pwd);

        if (thirdPartUser == null)
            throw new BizException(EnumReturnCode.NEED_LOGIN.getCode(), "账号密码错误！");

        UserInfo userInfo = userInfoDao.selectByPrimaryKey(thirdPartUser.getUserId());
        if (userInfo == null)
            throw new BizException(EnumReturnCode.NEED_LOGIN.getCode(), "数据异常，用户数据不存在！");
        return userInfo;
    }

    @Override
    public UserInfo loginByPhone(String phone, String code) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw new BizException(EnumReturnCode.NEED_LOGIN.getCode(), "phone或者code参数缺失！");
        }
        boolean phoneCheckResult = phoneCodeService.checkPhoneCode(phone, code);
        if (phoneCheckResult) {
            phoneCodeService.del(phone);
            UserInfo userInfo = userInfoDao.selectByPhone(phone);
            //如果用户不存在就创建
            if (userInfo == null) {
                userInfo = new UserInfo();
                userInfo.setId(id.nextId());
                userInfo.setPhone(phone);
                userInfo.setCountry("中国");
                UserInfo insert = this.insert(userInfo);
                return insert;
            }
            return userInfo;
        }
        throw new BizException(EnumReturnCode.NEED_LOGIN.getCode(), "短信验证码错误！");
    }


    @Override
    public UserInfo addUser(UserInfo userInfo) {
        if (userInfo.getId() == 0) {
            userInfo.setId(id.nextId());
        }
        this.userInfoDao.insert(userInfo);
        return userInfo;
    }

    @Override
    public UserInfo loginByWxPhone(String channel, WxUserInfo wxUserInfo) {
        ThirdPartUser thirdPartUser = thirdPartUserDao.selectByUnionId(channel, wxUserInfo.getUnionId());
        if (thirdPartUser == null) {
            UserInfo userInfo = beanMapper.map(wxUserInfo, UserInfo.class);
            userInfo.setId(id.nextId());
            UserInfo insert = this.insert(userInfo);
            thirdPartUser = new ThirdPartUser();
            thirdPartUser.setChannel(channel);
            thirdPartUser.setOpenId(wxUserInfo.getOpenId());
            thirdPartUser.setUnionId(wxUserInfo.getUnionId());
            thirdPartUser.setUserId(insert.getId());
            thirdPartUserDao.insert(thirdPartUser);
            return insert;
        } else {
            return userInfoDao.selectByPrimaryKey(thirdPartUser.getUserId());
        }
    }


    @Override
    public Class getTargetClass() {
        return UserInfo.class;
    }
}
